package com.o2o.service;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.o2o.base.BaseService;
import com.o2o.content.SessionContent;
import com.o2o.exception.CategoryNumberErrorException;
import com.o2o.model.topic.Category;
import com.o2o.model.topic.Product;
import com.o2o.model.topic.Topic;
import com.o2o.model.topic.TopicContent;
import com.o2o.model.user.User;
import com.o2o.sphinx.SortUtil;
import com.o2o.util.HBaseUtil;

@Scope("prototype")
@Service
public class TopicService extends BaseService{
	
	/**
	 * 获取全部的分类信息
	 * @param status
	 * @return List<Category>
	 */
	public List<Category> getAllCategoryTree(int status){
		return topicRepository.getAllCategoryTree(status);
	}
	
	/**
	 * 根据categoryNumber获取该number的一级分类
	 * @param categoryNumber 该分类的number
	 * @return 一级分类Category
	 */
	public Category getFirstCategoryByNumber(int categoryNumber,int status) throws Exception{
		return topicRepository.getFirstCategoryByNumber(categoryNumber,status);
	}
	/**
	 * 根据categoryNumber获取该number的二级分类
	 * @param categoryNumber 该分类的number
	 * @return 二级分类Category
	 * @throws CategoryNumberErrorException 分类number错误
	 */
	public Category getSecondCategoryByNumber(int categoryNumber,int status) throws CategoryNumberErrorException{
		return topicRepository.getSecondCategoryByNumber( categoryNumber,status);
	}
	/**
	 * 根据categoryNumber获取该number的三级分类
	 * @param categoryNumber 该分类的number
	 * @return 三级分类Category
	 * @throws CategoryNumberErrorException 分类number错误
	 */
	public Category getThirdCategoryByNumber(int categoryNumber,int status) throws CategoryNumberErrorException{
		return topicRepository.getThirdCategoryByNumber(categoryNumber,status);
	}
	/**
	 * 根据categoryNumber获取该number的四级分类
	 * @param categoryNumber 该分类的number
	 * @return 四级分类Category
	 * @throws CategoryNumberErrorException 分类number错误
	 */
	
	public Category getFourthCategoryByNumber(int categoryNumber,int status) throws CategoryNumberErrorException{
		return topicRepository.getFourthCategoryByNumber(categoryNumber,status);
	}
	/**
	 * 根据父分类id找到所有的子分类
	 * @param pid 父类分类id
	 * @return List<Category>所有的子分类
	 */
	public List<Category> getSubCategorysByPid(long pid,int status){
		return topicRepository.getSubCategorysByPid(pid,status);
	}
	/**
	 * 根据分类number找到所有的子分类
	 * @param categoryNumber 分类number
	 * @return List<Category>所有的子分类
	 * @throws CategoryNumberErrorException 分类number错误
	 */
	public List<Category> getSubCategorysByCategoryNumber(int categoryNumber,int status) throws CategoryNumberErrorException{
		return topicRepository.getSubCategorysByCategoryNumber(categoryNumber,status);
	}
	/**
	 * 保存主题帖和主题帖商品
	 * @param uid 用户id
	 * @param userName 用户的名称
	 * @param topicTitle 主题帖title
	 * @param topicString 主题帖的楼主说
	 * @param productName 商品名称
	 * @param productMarketPrice 商品市场价
	 * @param productCategoryNumber 商品分类number
	 * @param productPicturePath 商品主图的路径
	 * @param productBrand 商品品牌
	 * @param productType 商品的类型，1为标准品，2为本地生活服务，3为二手商品
	 * @param productUrl 商品的网上链接
	 * @param productDescription 商品描述
	 * @param topicPrice 主题帖的价格
	 * @return 序列化后的id,若保存失败，则返回0
	 * @throws Exception
	 */
	public long saveTopicAndProduct(final long uid, final String userName,final String topicTitle, final String topicString,final String productName, 
			final float productMarketPrice,final int productCategoryNumber, final String productPicturePath,final String productBrand, final int productType,final float topicPrice, final String productUrl,
			final String productDescription) throws Exception {
		long time = System.currentTimeMillis();
		long productId = topicRepository.saveProduct(productName,productMarketPrice, productCategoryNumber, productPicturePath,productBrand, productType, productUrl, productDescription,uid,time);
		if(productId > 0){
//			hBaseServiceRepository.saveAndUpdateProduct(productId, productName, productMarketPrice, productCategoryNumber, productPicturePath, productBrand, productType, productDescription, uid, 0, 0, time);
			long topicId = this.saveTopict(uid, productCategoryNumber,productType,topicPrice,userName, topicTitle, topicString,productName,productPicturePath, productId);
			return topicId;
		}else return 0;
	}
	/**
	 * 保存主题帖和主题帖商品
	 * @param uid 用户id
	 * @param userName 用户的名称
	 * @param categoryNumber 主题帖分类number
	 * @param topicTitle 主题帖title
	 * @param topicString 主题帖的楼主说
	 * @param productId 商品序列化id
	 * @return 序列化后的id,若保存失败，则返回0
	 * @throws Exception
	 */
	public long saveTopict(final long uid,final int categoryNumber,final int productType,final float topicPrice,final String userName,final String topicTitle, final String topicString,final String productName,final String productPicture,final long productId) throws Exception {
		final long time = System.currentTimeMillis();
		//mysql数据持久化
		long topicId = topicRepository.saveTopic(uid,userName,topicTitle,topicString,productId,categoryNumber,productType,topicPrice,time);
//		if(topicId > 0){
//			hBaseServiceRepository.saveAndUpdateTopic(topicId, categoryNumber,uid, userName, topicTitle, topicString, productId, 0, 0, 0, 0, 1, time);
//			hBaseServiceRepository.saveTopicCategoryNumber(topicId, productId, categoryNumber,productType, time);//保存主题帖和分类number关系
//		}
		return topicId;
	}
	/**
	 * 根据主题帖id获取该主题帖详细，带product信息
	 * @param topicId 主题帖id
	 * @return Product(带Topic信息)
	 * @throws IOException 
	 */
	public Topic getTopicProductByTopicId(long topicId) throws Exception {
//		Topic topic = hBaseServiceRepository.getTopicAndProductBytID(topicId);
//		if(topic != null){
//			return topic;
//		}else
			return topicRepository.getTopicProductByTopicId(topicId);
	}
	
	/**
	 * 保存主题帖讨论和讨论的回复
	 * @param topicId 主题帖id
	 * @param userId 发表的用户id
	 * @param content 讨论内容
	 * @param fatherId 回复评论的评论id，自关联，为0的话，是主题帖的讨论,fatherId>0是讨论的回复id
	 * @return 序列化后的id,若保存失败，则返回0
	 * @throws IOException 
	 */
	public long saveTopicContent(final long topicId,final long fromUserId,final long toUserId,final String content,final long fatherId,final long createTime) throws IOException{
		long tid = topicRepository.saveTopicContent(topicId, fromUserId,toUserId, content, fatherId,createTime);
//		if(tid > 0){
//			hBaseServiceRepository.saveTopicContent(tid, topicId, content, userId, 0, fatherId, createTime);
//		}
		return tid;
	}
	
	/**
	 * 根据主题帖topicId获取所有的主题帖讨论,如果下一页，则返回的条目数会比pageSize多1
	 * @param topicId 主题帖id
	 * @param page 当前页
	 * @param pageSize 分页大小
	 * @return List<TopicContent>
	 * @throws IOException 
	 */
	public List<TopicContent> getTopicContentByTopicId(long topicId,int page,int pageSize,Map<String,Object> session) throws IOException{
//		Map<String,String> pageCache = (Map<String, String>) session.get(SessionContent.SESSION_PAGE_CONTENT_CACHE);
//		String startRowKey = null;
//		String stopRowKey = null;
//		boolean rowFlag = false;//是否当前页的startRowKey为精确值
//		if(pageCache != null){
//			startRowKey = pageCache.get(""+topicId+page);//得到当前页的startRowKey，为null的话，可以直接传递进方法中
//			stopRowKey = pageCache.get(""+topicId+(page+1));//得到当前页的stopRowKey,为null的话，是默认的闭区间
//			if(startRowKey != null){
//				rowFlag = true;
//			}
//		}else{
//			pageCache = Collections.synchronizedMap(new HashMap<String,String>());
//		}
//		List<TopicContent> contents = hBaseServiceRepository.getTopicContentListByTid(topicId, page, pageSize,startRowKey,stopRowKey,rowFlag);
//		if(contents != null && !contents.isEmpty()){
//			String[] ids = new String[contents.size()];
//			int i = 0;
//			for (TopicContent topicContent : contents) {
//				ids[i++] = topicContent.getUserId()+"";
//			}
//			Map<Long, User> users = hBaseServiceRepository.getUserListByIds(ids);
//			for (TopicContent topicContent : contents) {
//				topicContent.setUser(users.get(topicContent.getUserId()));
//			}
//			//缓存分页数据,当前页的最后一个对象的rowKey是下一页的开始
//			if(contents.size() == pageSize+1){
//				//有下一页的数据
//				long tid = contents.get(contents.size()-1).getId();//取出列表的最后一个对象，获取rowKey进行缓存
//				long sortKey = Integer.MAX_VALUE - tid;
//				String number = HBaseUtil.numberChange(10, sortKey);
//				String rowKey = ""+topicId+number;
//				pageCache.put(""+topicId+(page+1), rowKey);
//			}
//			session.put(SessionContent.SESSION_PAGE_CONTENT_CACHE, pageCache);//更新操作
//		}else{
//			//穿透DB
//		contents = topicRepository.getTopicContentByTopicId(topicId, page, pageSize);
//		}
		return topicRepository.getTopicContentByTopicId(topicId, page, pageSize);
	}
	
	/**
	 * 保存用户赞的回复贴，若已经赞过，则该操作为取消赞
	 * @param contentId 回复帖id
	 * @param userId 操作的用户id
	 *	@return 1：赞成功，2：取消赞成功，0：操作失败
	 */
	public int saveTopicContentGreat(long topicId,long contentId,int type) throws IOException{
//		hBaseServiceRepository.updateTopicContentGreat(topicId, contentId, type);
		return topicRepository.saveTopicContentGreat(contentId, type);
	}

	/**
	 * 保存用户赞的主题帖，若已经赞过，则为取消赞
	 * @param topicId 回复帖id
	 * @param userId 用户id
	 * @return 1：赞成功，2：已经赞，0：操作失败
	 */
	public int saveTopicGreat(long topicId,long userId){
		return topicRepository.saveTopicGreatCount(topicId, userId);
	}
	
	/**
	 * 保存用户赞的回复，若已经赞过，则为取消赞
	 * @param contentId 回复id
	 * @param userId 用户id
	 * @return 1：赞成功，2：已经赞，0：操作失败
	 */
	public int saveContentGreat(long contentId,long userId){
		return topicRepository.saveTopicContentGreat(contentId, userId);
	}
	/**
	 * 根据categoryNumber获取所有对应的主题帖对象,每个topic对象中已经封装好了Product对象，如果下一页，则返回的条目数会比=pageSize+1
	 * @param categoryNumber 分类number
	 * @param productType 商品类型，1为标准商品，2为本地生活服务，3为二手商品
	 * @param page 页码
	 * @param pageSize 每页数量
	 * @param order 排序方式:1,以主题帖的热度,2发布时间倒序,///未实现3销量,4评分,5价格,默认为主题帖发布时间
	 * @return List<Topic>
	 * @throws IOException 
	 */
	public List<Topic> getTopicListByCategoryNumber(int categoryNumber,int productType,int order,int page,int pageSize,Map<String,Object> session) throws IOException{
		
		List<Topic> topics = topicRepository.getTopicListByCategoryNumber(categoryNumber, page, pageSize, order, productType);
		
//		Map<String,String> pageCache = (Map<String, String>) session.get(SessionContent.SESSION_PAGE_TOPIC_CACHE);
//		String startRowKey = null;
//		String stopRowKey = null;
//		boolean rowFlag = false;//是否当前页的startRowKey为精确值
//		if(pageCache != null){
//			startRowKey = pageCache.get(""+categoryNumber+productType+page);//得到当前页的startRowKey，为null的话，可以直接传递进方法中
//			stopRowKey = pageCache.get(""+categoryNumber+productType+(page+1));//得到当前页的stopRowKey,为null的话，是默认的闭区间
//			if(startRowKey != null){
//				rowFlag = true;
//			}
//		}else{
//			pageCache = Collections.synchronizedMap(new HashMap<String,String>());
//		} 
//		List<Topic> topics = hBaseServiceRepository.getTopicListByCategoryNumber(categoryNumber, productType,page, pageSize,startRowKey,stopRowKey,rowFlag);
//		if (topics != null && !topics.isEmpty()) {
//			String[] ids = new String[topics.size()];
//			int i = 0;
//			for (Topic topic : topics) {
//				ids[i++] = topic.getProductId() + "";
//			}
//			Map<Long, Product> products = hBaseServiceRepository.getProductListByIds(ids);
//			for (Topic topic : topics) {
//				topic.setProduct(products.get(topic.getProductId()));
//			}
//			//缓存分页数据,当前页的最后一个对象的rowKey是下一页的开始
//			if(topics.size() == pageSize+1){
//				//有下一页的数据
//				long tid = topics.get(topics.size()-1).getId();//取出列表的最后一个对象，获取rowKey进行缓存
//				long sortKey = Integer.MAX_VALUE - tid;
//				String number = HBaseUtil.numberChange(10, sortKey);
//				String rowKey = ""+productType+ topics.get(topics.size()-1).getProduct().getProductCategoryNumber()+number;
//				pageCache.put(""+categoryNumber+productType+(page+1), rowKey);
//			}
//			session.put(SessionContent.SESSION_PAGE_TOPIC_CACHE, pageCache);//更新操作
//		} else{
//			//穿透DB
//			return null;
//		}
		return topics;
	}
	
	/**
	 * 根据categoryNumber获取所有对应的主题帖对象,每个topic对象中已经封装好了Product对象，如果下一页，则返回的条目数会比=pageSize+1
	 * @param categoryNumber 分类number
	 * @param productType 商品类型，1为标准商品，2为本地生活服务，3为二手商品
	 * @param page 页码
	 * @param pageSize 每页数量
	 * @param order 排序方式:1,以主题帖的热度,2发布时间倒序,///未实现3销量,4评分,5价格,默认为主题帖发布时间
	 * @return List<Topic>
	 */
	public List<Topic> getTopicListBySphinxSearch(String q,int categoryNumber,int productType,int order,int page,int pageSize){
		int sort = 0;
		if(order == 1){
			sort = SortUtil.HOT_DESC;
		}
		if(order == 2){
			sort = SortUtil.DATA_DESC;
		}
		if(order == 3){
			sort = SortUtil.MATCH_DESC;
		}
		List<Topic> topics = null;
		try {
			topics = sphinxSearch.getSearchResult(sort, "", q, page, pageSize, categoryNumber,productType);
		} catch (Exception e) {
			logger.error("topic service sphinx search error;message:"+e.getMessage());
		}
		return topics;
	}
	/**
	 * 根据主题帖ids获取所有的主题帖讨论
	 * @param topicIds 主题帖id数组
	 * @return List<Topic>
	 * @throws IOException 
	 */
	public List<Topic> getTopicContentByTopicId(String[] ids) throws Exception{
		return topicRepository.getTopicProductListByTopicIds(ids);
		
	}
	/**
	 * 保存用户评论主题帖通知信息
	 * @param content 通知以及评论内容
	 * @param createTime 创建时间
	 * @param fromUserId 来自用户评论的user id
	 * @param toUserId 评论给用户的id
	 * @param topicId 评论的主题帖id
	 * @param contentId 评论的持久化id
	 * @param type 通知类型，1为评论主题帖，2为赞主题帖，3为回复评论，4为赞评论
	 * @return 持久化后的主键id，若为0则插入不成功
	 */
	public long saveTopicNotice(final long topicId,final String content,final long createTime,final long fromUserId,final long toUserId,final long contentId,final int type){
		return topicRepository.saveTopicNotice(topicId, content, createTime, fromUserId, toUserId,contentId,type);
	}
	
	/**
	 * 根据评论id获取评论的详细信息
	 * @param contentId 评论id 
	 * @return TopicContent
	 */
	public TopicContent getTopicContentById(long contentId){
		return topicRepository.getTopicContentById(contentId);
	}
}
